package service

import (
	"fmt"
	jsoniter "github.com/json-iterator/go"
	"homePageTemplate/model"
	"homePageTemplate/utils"
	"homePageTemplate/variable"
	"strings"
	"sync"
	"time"
)

type HomePageTemplateService struct {
	worker *utils.Worker
}

func NewHomePageTemplateService() *HomePageTemplateService {
	return &HomePageTemplateService{
		worker: utils.NewWorkerNovel(),
	}
}

func (hpts *HomePageTemplateService) EditHomePageDetails(chpd *model.CrudHomePageDetails) error {

	deleteErr := variable.Db.Where("home_page_template_id = ?", chpd.HomePageTemplateId).Delete(&model.HomePageDetails{}).Error
	if deleteErr != nil{
		return deleteErr
	}

	for _, hpd := range chpd.HomePageDetailList {
		hpd.Id = hpts.worker.GetId()
		hpd.HomePageTemplateId = chpd.HomePageTemplateId
		if hpd.ModuleAreaId == 431221432366661633 || hpd.ModuleAreaId == 431221432366661634 || hpd.ModuleAreaId == 431221432366661638 || hpd.ModuleAreaId == 431221432366661639 {
			jumpMode, err := jsoniter.Marshal(&hpd.SpikMode)
			if err != nil{
				return err
			}else {
				hpd.JumpMode = string(jumpMode)
			}

			if hpd.ModuleAreaId == 431221432366661634{
				rightJumpMode, rRrr := jsoniter.Marshal(&hpd.RightSpikMode)
				if rRrr != nil{
					return rRrr
				}else {
					hpd.RightJumpMode = string(rightJumpMode)
				}
			}
		}
		hpd.CreatedAt= time.Now()
		hpd.UpdatedAt= time.Now()
	}
	createErr := variable.Db.Create(chpd.HomePageDetailList).Error
	if createErr != nil {
		return createErr
	}

	return nil
}

func (hpts *HomePageTemplateService) EditHomePageDetailsAsync(chpd *model.CrudHomePageDetails) error {

	deleteErr := variable.Db.Where("home_page_template_id = ?", chpd.HomePageTemplateId).Delete(&model.HomePageDetails{}).Error
	if deleteErr != nil{
		return deleteErr
	}

	var wg sync.WaitGroup
	wg.Add(9)

	for i := 0; i < 9; i++ {
		var actuali int = i
		go func() error{
			defer func() {
				// 捕获异常 防止waitGroup阻塞
				if err := recover(); err != nil {
					wg.Done()
				}
			}()

			hpd := chpd.HomePageDetailList[actuali]
			hpd.Id = hpts.worker.GetId()
			hpd.HomePageTemplateId = chpd.HomePageTemplateId
			if hpd.ModuleAreaId == 431221432366661633 || hpd.ModuleAreaId == 431221432366661634 || hpd.ModuleAreaId == 431221432366661638 || hpd.ModuleAreaId == 431221432366661639 {
				jumpMode, err := jsoniter.Marshal(&hpd.SpikMode)
				if err != nil{
					return err
				}else {
					hpd.JumpMode = string(jumpMode)
				}

				if hpd.ModuleAreaId == 431221432366661634{
					rightJumpMode, rRrr := jsoniter.Marshal(&hpd.RightSpikMode)
					if rRrr != nil{
						return rRrr
					}else {
						hpd.RightJumpMode = string(rightJumpMode)
					}
				}
			}
			hpd.CreatedAt= time.Now()
			hpd.UpdatedAt= time.Now()

			wg.Done()

			return nil
		}()
	}

	wg.Wait()

	createErr := variable.Db.Create(chpd.HomePageDetailList).Error
	if createErr != nil {
		return createErr
	}

	return nil
}

func (hpts *HomePageTemplateService) QueryHomePageDetails(platformId int64) (*model.HomePageTemplate, error) {

	var hpt model.HomePageTemplate
	queryErr := variable.Db.First(&hpt).Error
	if queryErr != nil{
		return nil, queryErr
	}else {
		findErr := variable.Db.Where("home_page_template_id = ?", hpt.Id).Find(&hpt.HomePageDetailList).Error
		if findErr != nil {
			return nil, findErr
		}else {
			for _, hpd := range hpt.HomePageDetailList {
				if hpd.ModuleAreaId == 431221432366661631 || hpd.ModuleAreaId == 431221432366661632 || hpd.ModuleAreaId == 431221432366661637 {
					variable.Db.Joins("inner join advertising_types on advertising_types.id = advertising_contents.advertising_type_id").
						Where("advertising_types.code = ?", hpd.AdvertisementTypeCode).
						Find(&hpd.AdvertisingContentList)
				}

				if hpd.ModuleAreaId == 431221432366661633 {
					xyList := strings.Split(hpd.Coordinate, " | ")
					for index, xy := range xyList {
						spot := strings.Split(xy, ",")
						coordinateMap := map[int]interface{}{
							index : map[string]interface{}{
								"x" : spot[0],
								"y" : spot[1],
							},
						}
						hpd.CoordinateMapList = append(hpd.CoordinateMapList, coordinateMap)
					}
				}

				if hpd.ModuleAreaId == 431221432366661635 {
					variable.Db.Where("activity_type = ?", hpd.ActivityType).
						Where("status = ?", 2).
						Where("shelf = ?", 1).
						Find(&hpd.ActivitieList)
				}

				if hpd.ModuleAreaId == 431221432366661636 {
					idList := strings.Split(hpd.SpecificActivitiesList, ",")
					variable.Db.Where("id IN ?", idList).Find(&hpd.ActivitieList)
				}

				if hpd.ModuleAreaId == 431221432366661633 || hpd.ModuleAreaId == 431221432366661634 || hpd.ModuleAreaId == 431221432366661638 || hpd.ModuleAreaId == 431221432366661639 {
					dErr := jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal([]byte(hpd.JumpMode), &hpd.SpikMode)
					if dErr != nil{
						return nil, dErr
					}

					if hpd.ModuleAreaId == 431221432366661634{
						rErr := jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal([]byte(hpd.RightJumpMode), &hpd.RightSpikMode)
						if rErr != nil{
							return nil, rErr
						}
					}
				}
			}
		}
	}

	return &hpt, nil
}

func (hpts *HomePageTemplateService) QueryHomePageDetailsAsync(platformId int64) (*model.HomePageTemplate, error) {

	var hpt model.HomePageTemplate
	queryErr := variable.Db.Where("platform_id = ?", platformId).First(&hpt).Error
	if queryErr != nil{
		return nil, queryErr
	}else {
		findErr := variable.Db.Where("home_page_template_id = ?", hpt.Id).Find(&hpt.HomePageDetailList).Error
		if findErr != nil {
			return nil, findErr
		}else {
			if len(hpt.HomePageDetailList) > 0 {
				var wg sync.WaitGroup
				wg.Add(9)

				for i := 0; i < 9; i++ {
					var actuali int = i
					go func() error {
						defer func() {
							// 捕获异常 防止waitGroup阻塞
							if err := recover(); err != nil {
								wg.Done()
							}
						}()

						hpd := hpt.HomePageDetailList[actuali]
						if hpd.ModuleAreaId == 431221432366661631 || hpd.ModuleAreaId == 431221432366661632 || hpd.ModuleAreaId == 431221432366661637 {
							variable.Db.Joins("inner join advertising_types on advertising_types.id = advertising_contents.advertising_type_id").
								Where("advertising_types.code = ?", hpd.AdvertisementTypeCode).
								Find(&hpd.AdvertisingContentList)
						}

						if hpd.ModuleAreaId == 431221432366661633 {
							xyList := strings.Split(hpd.Coordinate, " | ")
							for index, xy := range xyList {
								spot := strings.Split(xy, ",")
								coordinateMap := map[int]interface{}{
									index: map[string]interface{}{
										"x": spot[0],
										"y": spot[1],
									},
								}
								hpd.CoordinateMapList = append(hpd.CoordinateMapList, coordinateMap)
							}
						}

						if hpd.ModuleAreaId == 431221432366661635 {
							variable.Db.Where("activity_type = ?", hpd.ActivityType).
								Where("status = ?", 2).
								Where("shelf = ?", 1).
								Find(&hpd.ActivitieList)
						}

						if hpd.ModuleAreaId == 431221432366661636 {
							idList := strings.Split(hpd.SpecificActivitiesList, ",")
							variable.Db.Where("id IN ?", idList).Find(&hpd.ActivitieList)
						}

						if hpd.ModuleAreaId == 431221432366661633 || hpd.ModuleAreaId == 431221432366661634 || hpd.ModuleAreaId == 431221432366661638 || hpd.ModuleAreaId == 431221432366661639 {
							dErr := jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal([]byte(hpd.JumpMode), &hpd.SpikMode)
							if dErr != nil {
								return dErr
							}

							if hpd.ModuleAreaId == 431221432366661634 {
								rErr := jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal([]byte(hpd.RightJumpMode), &hpd.RightSpikMode)
								if rErr != nil {
									return rErr
								}
							}
						}

						wg.Done()

						return nil
					}()
				}

				wg.Wait()
			}
		}
	}

	return &hpt, nil
}

func (hpts *HomePageTemplateService) QueryPageAll() (pageList []*model.Page, err error) {

	err = variable.Db.Find(&pageList).Error
	if err != nil{
		return nil, err
	}else {
		for _, page := range pageList {
			if page.PageParameters != "" {
				dErr := jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal([]byte(page.PageParameters), &page.PageParameterList)
				if dErr != nil {
					fmt.Println("dErr：", dErr)
					return nil, dErr
				}
			}
		}
	}

	return pageList, nil
}